package com.ztstkj.lzscale.ui

import android.annotation.SuppressLint
import android.app.AlertDialog
import android.graphics.Color
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.core.graphics.drawable.toDrawable
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.DeviceUtils
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.ToastUtils
import com.proembed.service.SilentInstallUtils
import com.sscl.baselibrary.utils.DebugUtil
import com.ztstkj.lzscale.R
import com.ztstkj.lzscale.adpters.CategoryItem
import com.ztstkj.lzscale.adpters.CategroyAdapter
import com.ztstkj.lzscale.databinding.ActivityMainBinding
import com.ztstkj.lzscale.fragments.UserFragment
import com.ztstkj.lzservices.cameras.CameraUtil
import com.ztstkj.lzservices.cameras.CameraXManager
import com.ztstkj.lzservices.dto.DeliveryInput
import com.ztstkj.lzservices.events.EventCard
import com.ztstkj.lzservices.events.EventCategory
import com.ztstkj.lzservices.events.EventRate
import com.ztstkj.lzservices.events.EventWeight
import com.ztstkj.lzservices.exceptions.apiCall
import com.ztstkj.lzservices.mmkvs.MmkvManager
import com.ztstkj.lzservices.networks.NetworkUtils
import com.ztstkj.lzservices.retrofits.Api
import com.ztstkj.lzservices.utils.FileUtil
import com.ztstkj.lzservices.utils.SpeakUtil
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.File

class MainActivity : ScaleActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var categroyAdapter: CategroyAdapter
    private lateinit var rateAdapter: CategroyAdapter
    private var cameraX: CameraXManager? = null
    private var curCategory: Int = 0
    private var curCategoryText: String = ""
    private var curRate: Int = 0
    private var curPoint: Int = 0
    private var curRateText: String = ""
    private val rates = listOf(
        CategoryItem("优", R.drawable.rate_excellent.toString(), 11, 3),
        CategoryItem("良", R.drawable.rate_good.toString(), 12, 2),
        CategoryItem("差", R.drawable.rate_bad.toString(), 13, 1),
        CategoryItem("空桶", R.drawable.rate_empty.toString(), 14, 0)
    )
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        init()
        initCameraX()
        initCategory()
        initRate()
        getTodaySummary()
    }


    @SuppressLint("SetTextI18n")
    private fun init() {
        val eq = MmkvManager.getEquipment()
        if (eq != null) {
            binding.tvSupervisorName.text = eq.supervisorName
            curEquipmentId = eq.id
            curDeptId = eq.deptId
        }
        runOnUiThread {  }
        //*************初始化摄像头
        binding.tvNoCamera.setOnClickListener {
            Log.i(tag, "检测是否有摄像头")
            if (CameraUtil.isCamera2(baseContext)) {
                initCameraX()
            } else {
                ToastUtils.showLong("未检测到摄像头设备", 3000)
            }
        }
    }
    @SuppressLint("SetTextI18n")
    private fun initCameraX() {
        if (CameraUtil.isCamera2(baseContext)) {
            cameraX = CameraXManager(this, binding.previewView)
            if (cameraX?.hasBackCamera() == true) {
                cameraX?.initPermission()
                binding.tvNoCamera.visibility = ViewGroup.GONE
                binding.previewView.visibility = ViewGroup.VISIBLE
            } else {
                binding.tvNoCamera.visibility = ViewGroup.VISIBLE
                binding.previewView.visibility = ViewGroup.GONE
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventCard(e: EventCard) {
        DebugUtil.debugOut(e.cardNo.toString())
        if (NetworkUtils.onLine) {
            getUserByCard(e.cardNo.toString(),e.modbus)
        } else {
            getUserByCardFromMkv(e.cardNo.toString(),e.modbus)
        }
    }
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventCategory(e: EventCategory) {
        curCategory = toLvsCategory(e.category)
        curCategoryText=getCategoryText(curCategory)
        if (curCategoryText.isNotEmpty()) SpeakUtil.speech(
            this@MainActivity,
            curCategoryText
        )
        runOnUiThread { categroyAdapter.selectReset(getCategoryPosition(curCategory)) }
    }
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventWeight(e: EventWeight) {
        curWeight = e.weight
        showWeight(e.isStable,curWeight)
    }
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventRate(e: EventRate) {
        curWeight = e.weight
        showWeight(false,curWeight)
        curRate = toLvsRate(e.rate)
        curRateText = "评价" + rates.find { it.value == curRate }?.name
        curPoint = rates.find { it.value == curRate }?.point ?: 0
        curCategory = toLvsCategory(e.category)
        if(e.cardNo>0){
            curCard = e.cardNo.toString()
        }
        runOnUiThread {
            binding.tvCurrentPoint.text = curPoint.toString()
            //binding.tvCurrentWeight.text = e.weight.toString()
            categroyAdapter.selectReset(getCategoryPosition(curCategory))
            rateAdapter.selectReset(getRatesPosition(curRate))
        }
        startDelivery()
    }

    //张工的编码转为绿能手
    private fun toLvsCategory(zgCategroy: Int): Int {
        //张工：1  易腐垃圾； 2 可回收       3 有害垃圾；   4 其他垃圾
        //后台：1  易腐垃圾   2 可回收       3 其他        4 有害
        when (zgCategroy) {
            1 -> return 1
            2 -> return 2
            3 -> return 4
            4 -> return 3
        }
        return 0
    }

    private fun toLvsRate(zgRate: Int): Int {
        //张工：1 为优； 2 为良； 3 为差； 4 为空桶；
        //后台：11      12       13      14
        when (zgRate) {
            1 -> return 11
            2 -> return 12
            3 -> return 13
            4 -> return 14
        }
        return 0
    }

    private fun getCategoryPosition(lvsCatetgory: Int): Int {
        var categoryIndex = -1
        for ((index, item) in categorys.withIndex()) {
            if (lvsCatetgory == item.value) categoryIndex = index
        }
        return categoryIndex
    }
    private fun getCategoryText(lvsCatetgory: Int): String{
        var categoryText = ""
        for (item in categorys)
            if (lvsCatetgory == item.value) categoryText = item.name
        return categoryText
    }

    private fun getRatesPosition(lvsRate: Int): Int {
        var rateIndex = -1
        for ((index, item) in rates.withIndex()) {
            if (lvsRate == item.value) rateIndex = index
        }
        return rateIndex
    }
    @SuppressLint("SetTextI18n")
    private fun showWeight(isStable: Boolean, weight: Int) {
        runOnUiThread {
            if (weight > 1000) {
                binding.tvCurrentWeightUnit.text = "千克"
                binding.tvCurrentWeight.text = "%.2f".format(weight.toDouble() / 1000)
            } else {
                binding.tvCurrentWeightUnit.text = "克"
                binding.tvCurrentWeight.text = weight.toString()
            }
            binding.tvMainWeightStable.text=if(isStable)"(稳定)" else "(波动)"
        }

    }

    private fun getTodaySummary() {
        lifecycleScope.launch {
            val resp = apiCall(false) { Api.get().getTodayDelivery(DeviceUtils.getAndroidID()) }
            val todaySummary = resp.data
            if (resp.success && todaySummary != null) {
                binding.tvSummaryHouse.text = todaySummary.persons.toString()
                binding.tvSummaryTotalWeight.text = todaySummary.weight.toString()
                binding.tvSummaryPerishable.text = todaySummary.perishable.toString()
                binding.tvSummaryOther.text = todaySummary.other.toString()
                binding.tvSummaryRecycle.text = todaySummary.recyclable.toString()
            }
        }
    }

    private fun initCategory() {
        val linearLayoutManager = LinearLayoutManager(this)
        linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
        val recyclerview = binding.recyclerCategory
        recyclerview.layoutManager = linearLayoutManager
        categroyAdapter = CategroyAdapter(categorys)
        recyclerview.adapter = categroyAdapter
        categroyAdapter.itemClickListener = object : CategroyAdapter.ICategoryItemClickListener {
            override fun onItemClickListener(position: Int) {
                curCategory = categorys[position].value
                curCategoryText = categorys[position].name
                if (curCategoryText.isNotEmpty()) SpeakUtil.speech(
                    this@MainActivity,
                    curCategoryText
                )
            }
        }

    }

    @OptIn(DelicateCoroutinesApi::class)
    private fun initRate() {

        val linearLayoutManager = LinearLayoutManager(this)
        linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
        val recyclerview = binding.recyclerRate
        recyclerview.layoutManager = linearLayoutManager
        rateAdapter = CategroyAdapter(rates)
        recyclerview.adapter = rateAdapter
        rateAdapter.itemClickListener = object : CategroyAdapter.ICategoryItemClickListener {
            override fun onItemClickListener(position: Int) {
                val selectData = rates[position]
                curRate = selectData.value
                curPoint = selectData.point
                curRateText = "评价" + selectData.name
                runOnUiThread { binding.tvCurrentPoint.text = curPoint.toString() }
                SpeakUtil.speech(this@MainActivity,"请将手移开准备拍照")
                Handler().postDelayed({
                    startDelivery()
                },curSetting.takePhotoDelay)
                /*
                Thread.sleep(1000)

                GlobalScope.launch {
                delay(1000)
                startDelivery()
                }
                */


            }
        }
    }

    override fun taskUpload() {
        val delivery = MmkvManager.getLastDelivery()
        if (delivery == null) {
            DebugUtil.debugOut("待上传记录：0")
            return
        }
        if(delivery.tryCount>=3){
            MmkvManager.removeDelivery(delivery.createTime.toString())
            MmkvManager.addLog("投递异常","尝试${delivery.tryCount}次数后失败，${GsonUtils.toJson(delivery)}")
            return
        }
        lifecycleScope.launch {
            if (delivery.trashCanPhotos.startsWith("/") && File(delivery.trashCanPhotos).exists()) {
                delivery.trashCanPhotos = FileUtil.imageBase64(delivery.trashCanPhotos)
            }
            val resp = apiCall { Api.get().postDelivery(delivery) }
            if (resp.success) {
                File(delivery.trashCanPhotos).delete()
                MmkvManager.removeDelivery(delivery.createTime.toString())
                taskUpload()
            }else{
                //添加尝试次数，将顺序滞后
                MmkvManager.removeDelivery(delivery.createTime.toString())
                delivery.createTime= System.currentTimeMillis()
                delivery.tryCount++
                MmkvManager.setDelivery(delivery)
            }

        }
    }

    private fun startDelivery() {
        if (cameraX != null) {
            cameraX?.takePhoto { url ->
                curPhotoPath = url
                DebugUtil.debugOut(url)
                curPhotoBase64 = FileUtil.imageBase64(url)
                deliveryAdd()
            }
        } else {
            deliveryAdd()
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun deliveryAdd() {
        if (curRateText.isNotEmpty()) SpeakUtil.speech(
            this@MainActivity,
            curRateText + "上传成功"
        )
        if (curCategory == 0) {
            SpeakUtil.speech(this@MainActivity, "请选择垃圾分类项")
            return
        }
        if (curWeight <= 0) {
            SpeakUtil.speech(this@MainActivity, text = "当前重量为零不上传数据")
            reset()
            return
        }
        lifecycleScope.launch {
            val deliveryInput = DeliveryInput()
            deliveryInput.deliveryUserId = curUserId
            deliveryInput.deliveryWeight = curWeight
            deliveryInput.deliveryCellId = curDeptId
            deliveryInput.icIdentifier = curCard
            deliveryInput.equipmentId = curEquipmentId
            deliveryInput.garbageCategory = curCategory
            deliveryInput.score = curRate
            deliveryInput.deliveryTimeLong = System.currentTimeMillis()
            deliveryInput.createTime=deliveryInput.deliveryTimeLong
            deliveryInput.appVersion = AppUtils.getAppVersionName()
            deliveryInput.trashCanPhotos = curPhotoBase64
            if (NetworkUtils.onLine) {
                //有网情况
                val resp = apiCall(false) { Api.get().postDelivery(deliveryInput) }
                if (resp.success) {
                    //FileUtil.delete(curPhotoPath)
                    getTodaySummary()
                } else {
                    deliveryInput.createTime=System.currentTimeMillis()
                    deliveryInput.tryCount++
                    deliveryInput.trashCanPhotos = curPhotoPath
                    MmkvManager.setDelivery(deliveryInput)
                }
            } else {
                //没网情况
                //binding.tvUserPoint.text = resp.data?.totalIntegral.toString()
                deliveryInput.trashCanPhotos = curPhotoPath
                MmkvManager.setDelivery(deliveryInput)
            }
            dialogSuccess()

        }
    }

    private fun reset() {
        curWeight = 0
        curRate = 0
        curRateText = ""
        curPhotoPath = ""
        curPhotoBase64 = ""
        binding.tvCurrentWeight.text = "0"
        binding.tvCurrentWeightUnit.text = "克"
        binding.tvCurrentPoint.text = "0"
        rateAdapter.selectReset()
    }

    /*
        fun popwindowSuccess() {
            var popupView =
                LayoutInflater.from(MainActivity@ this).inflate(R.layout.activity_success, null)
            val imgClose = popupView.findViewById<ImageView>(R.id.imgSuccessClose)
            var popupWindow = PopupWindow(MainActivity@ this)
            popupWindow.contentView = popupView
            popupWindow.isFocusable = true
            popupWindow.width = ViewGroup.LayoutParams.MATCH_PARENT
            popupWindow.height = ViewGroup.LayoutParams.MATCH_PARENT
            popupWindow.isClippingEnabled = true
            popupWindow.isOutsideTouchable = true
            window.attributes.alpha = 0.1f
            //popupWindow.setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
            //popupWindow.setBackgroundDrawable(BitmapDrawable())
            imgClose.setOnClickListener {
                popupWindow.dismiss()
            }
            //popupWindow.showAsDropDown(view,0,0)
            //Log.i("pop",popupWindow)
            //popupWindow.showAsDropDown(view)
            popupWindow.showAtLocation(
                binding.main, Gravity.CENTER, 0, 0
            )
        }
    */
    @SuppressLint("SetTextI18n")
    private fun dialogSuccess() {
        val builder = AlertDialog.Builder(this)
        val inflater: LayoutInflater = LayoutInflater.from(this)
        val dialogView = inflater.inflate(R.layout.activity_success, null)
        builder.setView(dialogView)
        val imgClose = dialogView.findViewById<ImageView>(R.id.imgSuccessClose)
        val tvCountDownTime = dialogView.findViewById<TextView>(R.id.tvCountDownTime)
        val tvCurPoint = dialogView.findViewById<TextView>(R.id.tvCurPoint)
        tvCurPoint.text = "+${curPoint}"
        val alertDialog = builder.create()
        alertDialog.window?.setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
        imgClose.setOnClickListener {
            alertDialog.dismiss()
        }
        alertDialog.setCancelable(true)//点击空白处不关闭
        alertDialog.show()
        val untilFinished = 4000L
        tvCountDownTime.text = (untilFinished / 1000).toString() + " 秒后自动关闭"
        val countDownTimer = object : CountDownTimer(untilFinished, 1000) {
            @SuppressLint("SetTextI18n")
            override fun onTick(millisUntilFinished: Long) {
                tvCountDownTime.text = (millisUntilFinished / 1000).toString() + " 秒后自动关闭"
            }
            override fun onFinish() {
                alertDialog.dismiss()
                if(curUser!=null){
                    curUser!!.totalPoint+=curPoint
                    updateUserFragment(UserFragment(curUser))
                }
                reset()
            }
        }
        countDownTimer.start()
    }

    private fun installApkV2(path: String) {
        DebugUtil.warnOut("安装：installApkV2")
        val result = SilentInstallUtils.install(path)
        DebugUtil.warnOut("安装：${result}")
    }

    private fun installApkV3(path: String) {
        DebugUtil.warnOut("安装：installApkV3")
        val result = SilentInstallUtils.install(path, baseContext, packageName, javaClass.name)
        DebugUtil.warnOut("安装：${result}")
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String?>, grantResults: IntArray, deviceId: Int) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults, deviceId)
    }

    override fun onDestroy() {
        super.onDestroy()
        cameraX?.shutDown()
    }
}